package com.jwell.IDcard.reader.api;

import com.jwell.IDcard.reader.Main;
import com.sun.jna.ptr.IntByReference;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author 唐旭
 * @version 1.0.0
 * @FileName:
 * @Company: 成都积微物联电子商务有限公司
 * @Date 2017/12/28
 * @remark:
 */
public class PhotoReader extends Thread {
    private final static String FILE_EXTENSION = ".wlt";
    private final static String TARGET_FILE_EXTENSION = ".bmp";
    private volatile boolean end = false;
    private int iPort = 1001;
    private List<Invoker> list = new CopyOnWriteArrayList<>();

    public synchronized void stopReader() {
        this.end = true;
    }

    public void addInvoker(Invoker invoker) {
        list.add(invoker);
    }

    public void removeInvoker(Invoker invoker) {
        list.remove(invoker);
    }

    public int getiPort() {
        return iPort;
    }

    public PhotoReader setiPort(int iPort) {
        this.iPort = iPort;
        return this;
    }

    @Override
    public void run() {
        SdtApi sdtApi = ApiFactory.getSdtApi();
        char[] pucCHMsg = new char[1024];
        IntByReference pucCHMsgLen = new IntByReference();

        byte[] pucPHMsg = new byte[1024];
        IntByReference puiPHMsgLen = new IntByReference();
        String photoPath;
        int result;
        try {
            sdtApi.SDT_OpenPort(iPort);

            while (!end) {
                int iIfOpen = 0;
                result = sdtApi.SDT_StartFindIDCard(iPort, new byte[4], iIfOpen);
                if (hasError(result)) {
                    Thread.sleep(1000);
                    continue;
                }
                result = sdtApi.SDT_SelectIDCard(iPort, new byte[8], iIfOpen);
                if (hasError(result)) {
                    Thread.sleep(1000);
                    continue;
                }

                result = sdtApi.SDT_ReadBaseMsg(iPort, pucCHMsg, pucCHMsgLen, pucPHMsg, puiPHMsgLen, iIfOpen);
                if (hasError(result)) {
                    Thread.sleep(1000);
                    continue;
                }
                String s = String.valueOf(pucCHMsg, 0, pucCHMsgLen.getValue());
                final IDCardInfo idCardInfo = new IDCardInfo(s);
                photoPath = savePhotoByte(pucPHMsg, puiPHMsgLen.getValue(), idCardInfo.getIDNumber());
                idCardInfo.setPhotoPath(photoPath.replaceAll(FILE_EXTENSION, TARGET_FILE_EXTENSION));
                PhotoDecoder photoDecoder = ApiFactory.getPhotoDecoder();
                result = photoDecoder.GetBmp(photoPath, 2);
                if (result != 1) {
                    throw new RuntimeException("相片解析失败,错误码:" + result);
                }
                for (Invoker invoker : list) {
                    invoker.invoke(idCardInfo);
                }

                Thread.sleep(3000);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            sdtApi.SDT_ClosePort(iPort);
        }
    }

    private boolean hasError(int result) {
        return !(result == 144 || result == 159);
    }

    private String savePhotoByte(byte[] pucPHMsg, int value, String idNumber) {
        String path = Main.class.getResource("").getPath().replaceFirst("/", "")
                .replaceAll("/", "\\\\");
        String pathname = path + idNumber + FILE_EXTENSION;
        try (FileOutputStream stream = new FileOutputStream(new File(pathname))) {
            stream.write(pucPHMsg, 0, value);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return pathname;
    }
}
